type OmitPrivateProp<T> = {
  [K in keyof T as K extends `#${string}` ? never : K]: T[K]
}

export class CatchError {
  constructor(p?: Partial<OmitPrivateProp<CatchError>>){
    Object.assign(this, p)
  }

  #loading?: { value: boolean }
  set loading(val: { value: boolean }){
    if(this.#loading) return 
    this.#loading = val
  }

  #success?: Function
  set success(fun: Function) { 
    this.#success = fun
  }

  #fail?: (err: any) => any
  set fail(fun: (err: any) => any) { 
    this.#fail = fun
  }

  #complete?: Function
  set complete(fun: Function) { 
    this.#complete = fun
  }
  set run(fun: () => any) {
    const handle = async () => {
      try {
        if (this.#loading) {
          if (this.#loading.value) return
          this.#loading.value = true
        }
        await fun()
        if (this.#loading) this.#loading.value = false
        this.#success?.()
      } catch (error: any) {
        const msg = error?.data?.msg || error
        if (msg && typeof msg === 'string') CatchError.prompt(msg)
        if (this.#loading) this.#loading.value = false
        this.#fail?.(error)
      } finally {
        this.#complete?.()
      }
    }
    handle()
  }

  static prompt(p: string | UniApp.ShowToastOptions) {
    const obj = typeof p === 'string' ? { title: p } : p
    uni.showToast({ icon: 'none', ...obj })
  }
}
